/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wwcontrolserver;

import java.net.*;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import wwcontrolserver.controls.AbstractControlState;
//import java.util.Date;

/**
 *
 * @author Michael Ferry
 */
public class WWControlServerMultiThread extends Thread{
    private Socket ClientSocket  = null;
    private WWControlServer WWCS;
    private ObjectOutputStream OutToClientObj;
    private ObjectInputStream InFromClientObj;
    private WWControlServerState WWCSStateFromClient;
    
    public WWControlServerMultiThread(WWControlServer control_arg,Socket socket){
        super("WWControlServerThread");
        ClientSocket = socket;
        WWCS = control_arg;
        //WWCSState = new WWControlServerState();
    }
    
    @Override
    public void run() {
        try {
            
            OutToClientObj = new ObjectOutputStream(ClientSocket.getOutputStream());
            InFromClientObj = new ObjectInputStream(ClientSocket.getInputStream());
            
            String OutMessage = "Client Connected";
            System.out.println(OutMessage);
            WWCS.WWCSLog.RecordLogEntry(OutMessage);

            //Send initial state of server to client
            SendMessage(OutToClientObj, WWCS.GetServerState());
            //Recieve initial command from server
            WWCSStateFromClient = RecieveMessage(InFromClientObj);

            while (WWCSStateFromClient.MessageFlag != WWControlServerState.StateFlags.CLOSE_CONNECTION && WWCSStateFromClient.MessageFlag != WWControlServerState.StateFlags.SHUTDOWN_SERVER) {
                ParseClientCommand(WWCSStateFromClient);
                SendMessage(OutToClientObj, WWCS.GetServerState());
                WWCSStateFromClient = RecieveMessage(InFromClientObj);
            }
            //Close Client Connection
            SendMessage(OutToClientObj, new WWControlServerState(WWControlServerState.StateFlags.CLOSE_CONNECTION));
            OutToClientObj.close();
            InFromClientObj.close();
            ClientSocket.close();
            OutMessage = "Client connection ended";
            System.out.println(OutMessage);
            WWCS.WWCSLog.RecordLogEntry(OutMessage);
            
            if(WWCSStateFromClient.MessageFlag == WWControlServerState.StateFlags.SHUTDOWN_SERVER){
                    WWCS.Exit();
                }
        } catch (IOException e) {
            WWCS.WWCSLog.RecordExceptionLogEntry(e);
        }
    }
    
    public void ParseClientCommand(WWControlServerState WWCSStateToParse) {
        switch (WWCSStateToParse.MessageFlag) {
            case CONTROL_UPDATE:
                for (AbstractControlState StateToProcess : WWCSStateToParse.StateOfControls) {
                    WWCS.CManager.SetControlState(StateToProcess);
                    
                }
                break;
            case SERVER_STATUS:
                //do nothing this is taken care of in the while loop above
                break;
        }




    }
    public WWControlServerState RecieveMessage(ObjectInputStream InStream) {
        try {
            try {
                return (WWControlServerState) InStream.readObject();
            } catch (ClassNotFoundException cf) {
                WWCS.WWCSLog.RecordExceptionLogEntry(cf);
                return null;
            }
        } catch (IOException ex) {
            WWCS.WWCSLog.RecordExceptionLogEntry(ex);
            return null;
            //Logger.getLogger(WWControlClientCommThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public void SendMessage(ObjectOutputStream OutStream, WWControlServerState WWCSStateToSend){
        try {
//            int x=1;
//            WWCSStateToServer.SetMessageID();
            OutStream.writeObject(WWCSStateToSend);
            OutStream.reset();
            OutStream.flush();
        } catch (IOException ex) {
            WWCS.WWCSLog.RecordExceptionLogEntry(ex);
            //Logger.getLogger(WWControlClientCommThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }         
}
